package com.herr.springboot.base.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.net.SocketTimeoutException;

/**
 * @author herr05
 */
@Aspect
@Component
public class LogAspect {

    public static final Logger log=LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("execution(public * com.herr.springboot.base.aop.controller.*.*(..))")
    public void controllerLogPointCut(){

    }

    @Pointcut("@annotation(com.herr.springboot.base.aop.aspect.MyLog)")
    public void annotationLogPointCut(){

    }

    @Before("controllerLogPointCut()")
    public void before(JoinPoint joinPoint){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        log.info("URL: "+request.getRequestURL().toString());
    }

    @After("controllerLogPointCut()")
    public void after(JoinPoint joinPoint){
        log.info("方法后执行");
    }

    @Around("controllerLogPointCut()")
    public Object arround(ProceedingJoinPoint pjp) throws Throwable{
        log.info("arround方法start.....");
        try {
            Object o =  pjp.proceed();
            log.info("arround方法proceed，结果是 :" + o);
            return o;
        } catch (Throwable e) {
            throw e;
        }
    }

    @AfterReturning(returning = "ret",pointcut = "controllerLogPointCut()")
    public void doAfterReturning(Object ret) throws Throwable{
        log.info("AfterReturning 返回：" + ret.toString());
    }

    @AfterReturning(returning = "ret",pointcut = "annotationLogPointCut()")
    public void doAfterReturning2(Object ret) throws Throwable{
        log.info("AfterReturning2 返回：" + ret.toString());
    }
}
